"""
cProfile 高级使用示例
演示高级功能：过滤、比较、可视化等
"""
import cProfile
import pstats
import io
import time
import re
from typing import List, Dict, Any
from functools import wraps


# ============================================================================
# 示例 1: 过滤和限制输出
# ============================================================================
def example_1_filtering() -> None:
    """示例1: 过滤特定函数"""
    print("\n" + "=" * 60)
    print("示例 1: 过滤和限制输出")
    print("=" * 60)
    
    def target_function():
        time.sleep(0.1)
        data = [i ** 2 for i in range(10000)]
        return sum(data)
    
    profiler = cProfile.Profile()
    profiler.enable()
    target_function()
    profiler.disable()
    
    stats = pstats.Stats(profiler)
    
    # 只显示包含特定关键字的函数
    print("\n只显示包含 'target' 的函数:")
    stats.print_stats('target')
    
    # 只显示前5项
    print("\n只显示前5项:")
    stats.sort_stats('time').print_stats(5)
    
    # 组合过滤
    print("\n组合过滤（包含 'sum' 或 'range'）:")
    stats.print_stats('sum|range')


# ============================================================================
# 示例 2: 调用者分析（Callers）
# ============================================================================
def function_a():
    function_b()
    function_c()

def function_b():
    time.sleep(0.05)
    function_c()

def function_c():
    time.sleep(0.02)


def example_2_callers() -> None:
    """示例2: 分析函数调用关系"""
    print("\n" + "=" * 60)
    print("示例 2: 调用者分析")
    print("=" * 60)
    
    profiler = cProfile.Profile()
    profiler.enable()
    function_a()
    profiler.disable()
    
    stats = pstats.Stats(profiler)
    
    # 显示谁调用了特定函数
    print("\n显示 function_c 的调用者:")
    stats.print_callers('function_c')
    
    # 显示特定函数调用了谁
    print("\n显示 function_a 调用的函数:")
    stats.print_callees('function_a')


# ============================================================================
# 示例 3: 多个 Profile 结果比较
# ============================================================================
def slow_algorithm(n: int) -> int:
    """慢速算法"""
    result = 0
    for i in range(n):
        for j in range(n):
            result += i * j
    return result


def fast_algorithm(n: int) -> int:
    """快速算法"""
    return sum(i * j for i in range(n) for j in range(n))


def example_3_comparison() -> None:
    """示例3: 比较两个实现的性能"""
    print("\n" + "=" * 60)
    print("示例 3: 性能比较")
    print("=" * 60)
    
    n = 500
    
    # 分析慢速算法
    profiler1 = cProfile.Profile()
    profiler1.enable()
    slow_algorithm(n)
    profiler1.disable()
    
    # 分析快速算法
    profiler2 = cProfile.Profile()
    profiler2.enable()
    fast_algorithm(n)
    profiler2.disable()
    
    # 分别显示
    print("\n慢速算法性能:")
    print("-" * 60)
    stats1 = pstats.Stats(profiler1)
    stats1.sort_stats('time').print_stats('slow_algorithm')
    
    print("\n快速算法性能:")
    print("-" * 60)
    stats2 = pstats.Stats(profiler2)
    stats2.sort_stats('time').print_stats('fast_algorithm')
    
    # 获取时间进行比较
    s1 = io.StringIO()
    s2 = io.StringIO()
    pstats.Stats(profiler1, stream=s1).print_stats()
    pstats.Stats(profiler2, stream=s2).print_stats()


# ============================================================================
# 示例 4: 上下文管理器
# ============================================================================
class ProfileContext:
    """性能分析上下文管理器"""
    
    def __init__(self, name: str = "Profile"):
        self.name = name
        self.profiler = cProfile.Profile()
    
    def __enter__(self):
        print(f"\n开始分析: {self.name}")
        self.profiler.enable()
        return self.profiler
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.profiler.disable()
        print(f"\n分析结果: {self.name}")
        print("-" * 60)
        stats = pstats.Stats(self.profiler)
        stats.sort_stats('cumulative').print_stats(10)


def example_4_context_manager() -> None:
    """示例4: 使用上下文管理器"""
    print("\n" + "=" * 60)
    print("示例 4: 上下文管理器")
    print("=" * 60)
    
    with ProfileContext("列表推导式"):
        result = [i ** 2 for i in range(100000)]
    
    with ProfileContext("生成器表达式"):
        result = list(i ** 2 for i in range(100000))


# ============================================================================
# 示例 5: 递归函数分析
# ============================================================================
def factorial(n: int) -> int:
    """递归计算阶乘"""
    if n <= 1:
        return 1
    return n * factorial(n - 1)


def example_5_recursive_analysis() -> None:
    """示例5: 分析递归函数"""
    print("\n" + "=" * 60)
    print("示例 5: 递归函数分析")
    print("=" * 60)
    
    profiler = cProfile.Profile()
    profiler.enable()
    
    # 计算多个阶乘
    for i in range(1, 11):
        factorial(i * 10)
    
    profiler.disable()
    
    stats = pstats.Stats(profiler)
    
    # 显示递归调用统计
    print("\n递归调用统计:")
    stats.sort_stats('calls').print_stats('factorial')
    
    # 显示累计时间
    print("\n按累计时间排序:")
    stats.sort_stats('cumulative').print_stats(5)


# ============================================================================
# 示例 6: 按模块分析
# ============================================================================
def example_6_module_analysis() -> None:
    """示例6: 按模块分析性能"""
    print("\n" + "=" * 60)
    print("示例 6: 按模块分析")
    print("=" * 60)
    
    import json
    import random
    
    profiler = cProfile.Profile()
    profiler.enable()
    
    # 使用多个模块
    data = {'numbers': [random.randint(1, 100) for _ in range(1000)]}
    json_str = json.dumps(data)
    parsed = json.loads(json_str)
    
    profiler.disable()
    
    stats = pstats.Stats(profiler)
    
    # 只显示 json 模块的函数
    print("\njson 模块的函数:")
    stats.print_stats('json')
    
    # 只显示 random 模块的函数
    print("\nrandom 模块的函数:")
    stats.print_stats('random')


# ============================================================================
# 示例 7: 统计信息提取
# ============================================================================
def example_7_stats_extraction() -> Dict[str, Any]:
    """示例7: 提取统计信息"""
    print("\n" + "=" * 60)
    print("示例 7: 提取统计信息")
    print("=" * 60)
    
    def test_function():
        return sum(i ** 2 for i in range(10000))
    
    profiler = cProfile.Profile()
    profiler.enable()
    test_function()
    profiler.disable()
    
    stats = pstats.Stats(profiler)
    
    # 获取原始统计数据
    stats_dict = stats.stats
    
    # 提取关键信息
    results = {
        'total_calls': stats.total_calls,
        'total_time': stats.total_tt,
        'functions': []
    }
    
    # 遍历每个函数的统计信息
    for func, (cc, nc, tt, ct, callers) in stats_dict.items():
        func_info = {
            'function': f"{func[0]}:{func[1]}:{func[2]}",
            'ncalls': nc,
            'tottime': tt,
            'cumtime': ct,
        }
        results['functions'].append(func_info)
    
    print(f"\n总调用次数: {results['total_calls']}")
    print(f"总时间: {results['total_time']:.6f}秒")
    print(f"\n前5个函数:")
    for func in sorted(results['functions'], key=lambda x: x['cumtime'], reverse=True)[:5]:
        print(f"  {func['function']}")
        print(f"    调用次数: {func['ncalls']}, 累计时间: {func['cumtime']:.6f}s")
    
    return results


# ============================================================================
# 示例 8: 性能报告生成
# ============================================================================
def generate_performance_report(profiler: cProfile.Profile, title: str = "性能报告") -> str:
    """生成格式化的性能报告"""
    s = io.StringIO()
    stats = pstats.Stats(profiler, stream=s)
    
    s.write(f"\n{'=' * 80}\n")
    s.write(f"{title:^80}\n")
    s.write(f"{'=' * 80}\n\n")
    
    # 总体统计
    s.write(f"总调用次数: {stats.total_calls}\n")
    s.write(f"总执行时间: {stats.total_tt:.6f} 秒\n\n")
    
    # 按不同维度排序
    s.write(f"\n{'-' * 80}\n")
    s.write("按累计时间排序（前10项）:\n")
    s.write(f"{'-' * 80}\n")
    stats.sort_stats('cumulative').print_stats(10)
    
    s.write(f"\n{'-' * 80}\n")
    s.write("按调用次数排序（前10项）:\n")
    s.write(f"{'-' * 80}\n")
    stats.sort_stats('calls').print_stats(10)
    
    return s.getvalue()


def example_8_report_generation() -> None:
    """示例8: 生成性能报告"""
    print("\n" + "=" * 60)
    print("示例 8: 性能报告生成")
    print("=" * 60)
    
    def complex_task():
        # 模拟复杂任务
        data = []
        for i in range(100):
            data.append([j ** 2 for j in range(100)])
        return sum(sum(row) for row in data)
    
    profiler = cProfile.Profile()
    profiler.enable()
    complex_task()
    profiler.disable()
    
    report = generate_performance_report(profiler, "复杂任务性能分析")
    print(report)


# ============================================================================
# 主函数
# ============================================================================
def run_all_examples() -> None:
    """运行所有高级示例"""
    print("cProfile 高级使用示例")
    print("=" * 80)
    
    example_1_filtering()
    example_2_callers()
    example_3_comparison()
    example_4_context_manager()
    example_5_recursive_analysis()
    example_6_module_analysis()
    example_7_stats_extraction()
    example_8_report_generation()


if __name__ == '__main__':
    run_all_examples()
